package uk.ac.bath.domains.prey;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.text.DecimalFormat;
import java.util.Observable;
import java.util.Vector;

import uk.ac.bath.base.Cell;
import uk.ac.bath.base.Point;
import uk.ac.bath.gui.View;

public class PreyView extends View { 

    private int w,  h;

    //    TweakableInt observeThresh;
//     boolean skip;
//     boolean skipLast;
    Vector<Cell> population = new Vector<Cell>(); // to make a copy to avoid concurrency
    PreyViewable env;
    float fitref;
    boolean dbg = false;

    public PreyView(PreyViewable env) {

        this.env = env;
        h = env.getSpace().sizeY();
        w = env.getSpace().sizeX();
        setBackground(Color.black);
        setDoubleBuffered(true);
        //	observeThresh=new TweakableInt(0,1000,20,"Display if fit > ");
        fitref = 0.1f;
    }

    public void setDebug(boolean flag) {
        dbg = flag;
    }

    public void update(Observable subject, Object d) {
        repaint();
    }


//     public Dimension getPreferredSize() {
//  	return new Dimension(w,h);
//     }
    public void myPaint(Graphics g1) {
        //super.paintComponent(g1);

        Graphics2D g = (Graphics2D) g1;

        g.setColor(Color.white);
        g.drawString(Integer.toString(env.getTickCount()), getWidth() - 100, getHeight() - 20);


        Graphics2D go = (Graphics2D) g.create();

        double xScale = getWidth() / (double) w;
        double yScale = getHeight() / (double) h;
        g.scale(xScale, yScale);


        PreySpace space = (PreySpace) env.getSpace();



        HunterCell hunter = env.getHunter();
        if (hunter==null) return;
        
        PreyCell prey= env.getPrey();

        //synchronized (env.getMuex()) {
            population.clear();
            population.add(hunter);
             population.add(prey);
        //}


        int iy = 10;
        int ix = 10;
        int ih = 12;

        DecimalFormat f = new DecimalFormat("####.###");

        int homeH = 20;

        int x = (int) (((PreySpace) env.getSpace()).home.getX() * xScale);
        int y = (int) (((PreySpace) env.getSpace()).home.getY() * yScale);

        go.setColor(Color.GRAY);
        go.drawRect(x - homeH, y - homeH, 2 * homeH, 2 * homeH);

        Stroke oS = go.getStroke();
        go.setStroke(new BasicStroke(3.0f));

        go.setColor(Color.WHITE);
        for (Wall ww : space.walls) {
            go.drawLine((int) (ww.p1.x * xScale), (int) (ww.p1.y * yScale), (int) (ww.p2.x * xScale), (int) (yScale * ww.p2.y));

        }

        go.setStroke(oS);

        for (int i = 0; i < population.size(); i++) {
            Cell cell = (Cell) (population.elementAt(i));
            //	    g.setColor(color[i%nColors]);



            float hue; //  = cell.getId() / 6.1f; // 0-1
            float sat;  // = 1.0f; // 0-1

            if (cell instanceof HunterCell) {

                hue = (float) ((cell.getId() % 100.0) / 6.1);
                sat = 1.0f;

            } else {
                hue = 0.7f;
                sat = 1.0f;
            }

            float fit = (float) cell.getFitness();
            if (fit < 0) {
                continue;
            }
            fitref = Math.max(fit, fitref * 0.95f);
            float bri = 0.5f + 10 * fit / fitref;
            if (bri > 1.0f) {
                bri = 1.0f;
            }

            go.setColor(Color.getHSBColor(hue, sat, bri));

            if (i < 30 && dbg) {
                go.drawString("[" + cell.getTag() + "] " + cell.getGeneration() +
                        ":" + cell.getAge() + ":" + f.format(cell.getFitness()), ix, iy + ih * i);
            }

            Point p1 = cell.getPoint();

            double x1 = (p1.getX()) * xScale;
            double y1 = (p1.getY()) * yScale;
            // 	    go.drawString(String.valueOf(cell.getGeneration()),
            // 			  (float)(x1-cw),(float)(y1+ch));

            int d = 9;
            if (cell instanceof HunterCell) {
                if (((HunterCell) cell).hasCaptured()) {
                    go.fillArc((int) (x1 - d), (int) (y1 - d), 2 * d, 2 * d, 0, 360);
                } else {
                    go.drawArc((int) (x1 - d), (int) (y1 - d), 2 * d, 2 * d, 0, 360);
                }
            } else {
                go.fillArc((int) (x1 - d), (int) (y1 - d), 2 * d, 2 * d, 0, 360);
            }

        }



        // go.translate(getWidth() / 2, getHeight() - monitH - 2);

        MyPoint p0 = (MyPoint) hunter.getPoint();

        double x0 = (p0.getX()) * xScale;
        double y0 = (p0.getY()) * yScale;

//            go.drawLine((int) x1, (int) y1, (int) x0, (int) y0);

        go.translate(x0, y0);


        int ang = hunter.preyScannerResolution;

        //  System.out.print(hunter.preySector);

        double myAng = (hunter.dir.getAngle() * 180.0 / Math.PI);
        if (myAng < 0) {
            myAng += 360;
        }
        int monitH = 30;

        Integer pS = hunter.preySector;

        if (pS != null) {
            go.setColor(Color.RED);
            go.drawArc(-monitH / 2, -monitH / 2, monitH, monitH, (int) (-(myAng + pS * ang)), -ang);
        }

        Integer hS = hunter.homeSector;

        if (hS != null) {
            go.setColor(Color.GREEN);
            go.drawArc(-monitH / 2 + 2, -monitH / 2 + 2, monitH - 4, monitH - 4, (int) (-(myAng + hS * ang)), -ang);
        }


        // counter-clockwise (fillarc) is oposite sense to atan2 !!!!
        // }

        go.setColor(Color.GRAY);

        float xx = hunter.dir.x * monitH;
        float yy = hunter.dir.y * monitH;

        go.drawLine(0, 0, (int) xx, (int) yy);


    //	g.drawImage(bimg, 0, 0, getWidth(),getHeight(),0,0,w,h,this);
    // env.displayDone();

    }
}


